﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using IntroduceCompany.Util;
using IntroduceCompany.Singleton;
using System.Net.Mail;
using System.Net;
using System.ComponentModel.DataAnnotations;


namespace IntroduceCompany.Models
{
    //[Serializable]
    public class  ProductInCart
    {
        private String _ProductID;
        private String _ProductName;
        private String _ProductImage;
        private double _Price;
        private int _Quantity;
        private double _CurrencyExchangeRates_VN_USD;

        public String ProductID
        {
            get
            {
                return this._ProductID;
            }

            set
            {
                if ((this._ProductID != value))
                {
                    this._ProductID = value;
                }
            }
        }

        public String ProductName
        {
            get
            {
                return this._ProductName;
            }

            set
            {
                if ((this._ProductName != value))
                {
                    this._ProductName = value;
                }
            }
        }

        public String ProductImage
        {
            get
            {
                return this._ProductImage;
            }
            set
            {
                if ((this._ProductImage != value))
                {
                    this._ProductImage = value;
                }
            }
        }

        public double Price
        {
            get
            {
                return this._Price;
            }
            set
            {
                if ((this._Price != value))
                {
                    this._Price = value;
                }
            }
        }

        public int Quantity
        {
            get
            {
                return this._Quantity;
            }
            set
            {
                if ((this._Quantity != value))
                {
                    this._Quantity = value;
                }
            }
        }

        public double CurrencyExchangeRates_VN_USD
        {
            get
            {
                return this._CurrencyExchangeRates_VN_USD;
            }
            set
            {
                if ((this._CurrencyExchangeRates_VN_USD != value))
                {
                    this._CurrencyExchangeRates_VN_USD = value;
                }
            }
        }

        public double PriceUSD
        {
            get
            {
                return this._Price * this._CurrencyExchangeRates_VN_USD;
            }
            
        }

        public double TotalMoney
        {
            get
            {
                return (this.Price * this.Quantity);
            }
        }

    }


    public class OrderStatus
    {
        public String orderStatusID { get; set; }
        public String orderStatusName { get; set; }
    }


    public class CurrencyExchangeRate_Validation
    {
        //[System.ComponentModel.DataAnnotations.MetadataType(typeof(IntroduceCompany.Models.CurrencyExchangeRate_Validation))]
        [Required(ErrorMessage = "Tên tiền tệ phải có.")]
        public String CurrencyName { get; set; }

        [Required(ErrorMessage = "Tỷ lệ tiền tệ VN-USD phải có.")]
        [RegularExpression(ConstantClass.testCurrencyExchangeRate, ErrorMessage = "Tỷ giá tiền tệ không đúng kiểu thập phân.")]
        public String Rate { get; set; }

    }

    public class OrderMaster_Validation
    {
        //[System.ComponentModel.DataAnnotations.MetadataType(typeof(IntroduceCompany.Models.OrderMaster_Validation))]

        [Required(ErrorMessageResourceName = "Universal_ValidateString_Require", ErrorMessageResourceType = typeof(IntroduceCompany.Resources.Resx))]
        [LocalizedDisplayName("Frontend_Order_Order_lab_ClientName", NameResourceType = typeof(IntroduceCompany.Resources.Resx))]
        public String ClientName { get; set; }

        [Required(ErrorMessageResourceName = "Universal_ValidateString_Require", ErrorMessageResourceType = typeof(IntroduceCompany.Resources.Resx))]
        [RegularExpression(ConstantClass.testEmailRegular_1, ErrorMessageResourceName = "Universal_ValidateString_Email", ErrorMessageResourceType = typeof(IntroduceCompany.Resources.Resx))]
        [LocalizedDisplayName("Frontend_Order_Order_lab_Email", NameResourceType = typeof(IntroduceCompany.Resources.Resx))]
        public string Email { get; set; }

        [Required(ErrorMessageResourceName = "Universal_ValidateString_Require", ErrorMessageResourceType = typeof(IntroduceCompany.Resources.Resx))]
        [RegularExpression(ConstantClass.testPhoneRegular_1, ErrorMessageResourceName = "Universal_ValidateString_Phone", ErrorMessageResourceType = typeof(IntroduceCompany.Resources.Resx))]
        [LocalizedDisplayName("Frontend_Order_Order_lab_Phone", NameResourceType = typeof(IntroduceCompany.Resources.Resx))]
        public string Phone { get; set; }

        [Required(ErrorMessageResourceName = "Universal_ValidateString_Require", ErrorMessageResourceType = typeof(IntroduceCompany.Resources.Resx))]
        [LocalizedDisplayName("Frontend_Order_Order_lab_Address", NameResourceType = typeof(IntroduceCompany.Resources.Resx))]
        public String Address { get; set; }


    }
    

    public class OrderModels
    {

        /// <summary>
        /// Get product list in cart
        /// </summary>
        /// <param name="cookielist">Cookie contain list of productID and quantity</param>
        /// <param name="languageID"></param>
        /// <returns></returns>
        internal List<IntroduceCompany.Models.ProductInCart> GetCart(HttpCookie cookielist, String languageID)
        {

            List<IntroduceCompany.Models.ProductInCart> productListCart = null;
            if (cookielist.HasKeys)
            {
                System.Globalization.CultureInfo EnglishCulture = new System.Globalization.CultureInfo("en-US");
                double _currencyExchangeRates_VN_USD = Convert.ToDouble(DataSingleton.GetInstance().CurrencyExchangeRates.SingleOrDefault(c => c.CurID == 1).Rate, EnglishCulture);
                productListCart = new List<ProductInCart>();
                System.Collections.Specialized.NameValueCollection cookiecoll = cookielist.Values;
                String[] keyList = cookiecoll.AllKeys;

                Product product;
                Product_L productL;
                IntroduceCompany.Models.ProductInCart productInCart;
                String productID = "";
                for (int i = 0; i < keyList.Length; i++)
                {
                    productID = keyList[i];

                    product = DataSingleton.GetInstance().Products.SingleOrDefault(p => p.ProductID == productID && p.Visible == true);
                    if (product != null)
                    {
                        productL = DataSingleton.GetInstance().Product_Ls.SingleOrDefault(p => p.ProductID == productID && p.LanguageID == languageID);
                        productInCart = new ProductInCart();
                        productInCart.ProductID = productID;
                        productInCart.ProductName = (productL == null ? "????" : productL.ProductName);
                        productInCart.Quantity = Convert.ToInt16(cookielist.Values[productID].ToString());
                        productInCart.Price = product.ProductPrice;
                        productInCart.CurrencyExchangeRates_VN_USD = _currencyExchangeRates_VN_USD;

                        productListCart.Add(productInCart);
                    }

                }
            }

            return productListCart;

        }



        /// <summary>
        /// Insert Order into database
        /// </summary>
        /// <param name="orderMaster"></param>
        /// <param name="httpCookie"></param>
        internal int CreateOrder(OrderMaster orderMaster, HttpCookie cookielist, String languageID)
        {
            int newOrderID = 0;
            try
            {
                newOrderID = DataSingleton.GetInstance().sp_OrderMasterInsert(orderMaster.ClientName.Trim(), orderMaster.Phone.Trim()
                    , orderMaster.Email.Trim(), orderMaster.Address.Trim());
                
                if (cookielist.HasKeys)
                {
                    System.Globalization.CultureInfo EnglishCulture = new System.Globalization.CultureInfo("en-US");
                    double _currencyExchangeRates_VN_USD = Convert.ToDouble(DataSingleton.GetInstance().CurrencyExchangeRates.SingleOrDefault(c => c.CurID == 1).Rate, EnglishCulture);
                    System.Collections.Specialized.NameValueCollection cookiecoll = cookielist.Values;
                    String[] keyList = cookiecoll.AllKeys;

                    String productID = "";
                    Product product;
                    Product_L productL;
                    OrderDetail orderDetail;
                    for (int i = 0; i < keyList.Length; i++)
                    {
                        productID = keyList[i];

                        product = DataSingleton.GetInstance().Products.SingleOrDefault(p => p.ProductID == productID);

                        if (product != null)
                        {
                            productL = DataSingleton.GetInstance().Product_Ls.SingleOrDefault(p => p.ProductID == productID && p.LanguageID == languageID);

                            orderDetail = new OrderDetail();
                            orderDetail.OrderID = newOrderID;
                            orderDetail.ProductID = productID;
                            orderDetail.ProductName = (productL == null ? "????" : productL.ProductName);
                            orderDetail.ProductPrice = product.ProductPrice;
                            orderDetail.Quantity = Convert.ToInt16(cookielist.Values[productID].ToString());
                            orderDetail.ProductPriceUSD = product.ProductPrice * _currencyExchangeRates_VN_USD;

                            DataSingleton.GetInstance().OrderDetails.InsertOnSubmit(orderDetail);
                            DataSingleton.GetInstance().OrderDetails.Context.SubmitChanges();

                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);

                // Delete Order Master when occur error
                try
                {
                    DataSingleton.GetInstance().OrderMasters.DeleteOnSubmit(DataSingleton.GetInstance().OrderMasters.SingleOrDefault(o => o.OrderID == newOrderID));
                    DataSingleton.GetInstance().OrderMasters.Context.SubmitChanges();
                }
                catch (Exception exp)
                {
                    Console.WriteLine(ex.Message);
                }

                return 0;
            }
            return newOrderID;
        }



        /// <summary>
        /// Send order to client
        /// </summary>
        internal void CreateAndSendMail(int orderID)
        {
            try
            {
                //string contentMail = CreateContentMail(orderID);
                OrderMaster orderMaster = DataSingleton.GetInstance().OrderMasters.SingleOrDefault(o => o.OrderID == orderID);
                IQueryable<OrderDetail> orderDetailList = DataSingleton.GetInstance().OrderDetails.Where(o => o.OrderID == orderID);

                String contentBody = "<h3>Xin chào," + orderMaster.ClientName + "<h3><br/><br/>";
                contentBody += "Đây là danh sách sản phẩm bạn đã đặt hàng từ " + IntroduceCompany.Resources.Resx.OrderModels_CreateAndSendMail_CompanyName + "<br/><br/>";
                double totalMoney = 0;

                foreach (var item in orderDetailList){
                    contentBody += "Sản phẩm: " + item.ProductName + "  Số lượng: " + item.Quantity + " Giá: " + item.ProductPrice + " Thành tiền: " 
                        + (item.ProductPrice * item.Quantity) + " VND";
                    totalMoney += item.ProductPrice * item.Quantity;
                }

                contentBody += "<br/> <p>Tổng cộng: </p>" + totalMoney + " VND";
                contentBody += "<br/><br/>" + "Đơn hàng sẽ được gửi tới địa chỉ: " + orderMaster.Address;
                contentBody += "<br/>" + "Chúng tôi sẽ liên lạc với bạn qua số điện thoại: " + orderMaster.Phone;
                contentBody += "<br/><br/>" + "Xin chân thành cảm ơn.";


                SendMail(IntroduceCompany.Resources.Resx.OrderModels_CreateAndSendMail_CompanyEmail, orderMaster.Email,
                    IntroduceCompany.Resources.Resx.OrderModels_CreateAndSendMail_EmailSubject, contentBody, orderMaster.ClientName);
                

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }


        /// <summary>
        /// Send email
        /// </summary>
        /// <param name="orderID"></param>
        private void SendMail(String fromEmail, String toEmail, String subject, String contentBody, String clientName)
        {
            BossEmail bossEmail = DataSingleton.GetInstance().BossEmails.First(u => u.Active ==true);
            try
            {
               // System.Net.Mail.MailMessage msgSe = new System.Net.Mail.MailMessage();
                MailAddress from = new MailAddress(bossEmail.Email, bossEmail.SenderName);
                MailAddress to = new MailAddress(toEmail, clientName);
                MailMessage msgSe = new MailMessage(from, to);

                msgSe.Subject = subject;
                msgSe.Priority = System.Net.Mail.MailPriority.High;
                msgSe.IsBodyHtml = true;
                msgSe.Body = contentBody;

                // Add a carbon copy recipient.
                //MailAddress copy = new MailAddress("Notification_List@contoso.com");
                //msgSe.CC.Add(copy);
                string pass = Crypto.DecryptStringAES(bossEmail.Pass, ConstantClass._DecryptPass);
                SmtpClient client = new SmtpClient(bossEmail.SmtpServer, bossEmail.Port)
                {
                    Credentials = new NetworkCredential(bossEmail.Email, pass),
                    EnableSsl = bossEmail.SSL
                };
                
                // Include credentials if the server requires them.
                client.Credentials = CredentialCache.DefaultNetworkCredentials;
                client.UseDefaultCredentials = false;
                System.Net.NetworkCredential theCredential = new System.Net.NetworkCredential(bossEmail.Email, pass);
                client.Credentials = theCredential;

                client.Send(msgSe);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }



        /// <summary>
        /// Make Order Status List
        /// </summary>
        /// <param name="languageID"></param>
        /// <returns></returns>
        internal List<OrderStatus> MakeOrderStatusList()
        {
            List<OrderStatus> orderStatusList = new List<OrderStatus>();
            //Add menu "None" with ID = 0
            OrderStatus orderStatus = new OrderStatus();
            orderStatus.orderStatusID = "";
            orderStatus.orderStatusName = "Xem tất cả";
            orderStatusList.Add(orderStatus);

            orderStatus = new OrderStatus();
            orderStatus.orderStatusID = "0";
            orderStatus.orderStatusName = "Chưa giao";
            orderStatusList.Add(orderStatus);

            orderStatus = new OrderStatus();
            orderStatus.orderStatusID = "1";
            orderStatus.orderStatusName = "Đã giao";
            orderStatusList.Add(orderStatus);

            return (orderStatusList);
        }


        /// <summary>
        /// Get order list filter by order status
        /// </summary>
        /// <param name="orderStatusID"></param>
        /// <returns></returns>
        internal IQueryable<OrderMaster> GetOrderList(String orderStatusID)
        {
            if (orderStatusID == "")
            {
                return DataSingleton.GetInstance().OrderMasters.OrderByDescending(o => o.OrderID);
            }
            else
            {
                return DataSingleton.GetInstance().OrderMasters.Where(o => o.OrderStatus == (orderStatusID=="1"?true:false)) .OrderByDescending(o => o.OrderID);
            }
        }



        /// <summary>
        /// Update order status
        /// </summary>
        /// <param name="orderID"></param>
        /// <param name="status"></param>
        internal void UpdateOrderStatus(int orderID, bool status)
        {
            try
            {
                OrderMaster order = DataSingleton.GetInstance().OrderMasters.SingleOrDefault(o => o.OrderID == orderID);
                order.OrderStatus = !status;
                DataSingleton.GetInstance().OrderMasters.Context.SubmitChanges();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }


        /// <summary>
        /// Delete a order
        /// </summary>
        /// <param name="orderID"></param>
        internal void DeleteOrder(int orderID)
        {
            try
            {
                DataSingleton.GetInstance().OrderMasters.DeleteOnSubmit(DataSingleton.GetInstance().OrderMasters.SingleOrDefault(o => o.OrderID == orderID));
                DataSingleton.GetInstance().OrderMasters.Context.SubmitChanges();

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }


        /// <summary>
        /// Get information of a order in order master table
        /// </summary>
        /// <param name="orderID"></param>
        /// <returns></returns>
        internal OrderMaster GetOrderMasterDetails(int orderID)
        {
            return DataSingleton.GetInstance().OrderMasters.SingleOrDefault(o => o.OrderID == orderID);
        }


        /// <summary>
        /// Get product list in a order
        /// </summary>
        /// <param name="orderID"></param>
        /// <returns></returns>
        internal IQueryable<OrderDetail> GetProductListInOrder(int orderID)
        {
            return DataSingleton.GetInstance().OrderDetails.Where(o => o.OrderID == orderID);
        }

        /// <summary>
        /// Get first record in CurrencyExchangeRate table
        /// </summary>
        /// <returns></returns>
        internal CurrencyExchangeRate GetCurrencyExchangeRates()
        {
            CurrencyExchangeRate tempCur = DataSingleton.GetInstance().CurrencyExchangeRates.First();
            //CurrencyRate curEntity = new CurrencyRate();
            //curEntity.CurID = tempCur.CurID;
            //curEntity.CurrencyName = tempCur.CurrencyName;
            //curEntity.Rate = tempCur.Rate.ToString();
         //   curEntity.Rate = tempCur.Rate.ToString("0,0.0000000");

            return tempCur;
        }


        /// <summary>
        /// Update Currency rate
        /// </summary>
        internal bool CurrencyExchangeRatesEdit(CurrencyExchangeRate currency)
        {
            try
            {
                CurrencyExchangeRate tempCur = DataSingleton.GetInstance().CurrencyExchangeRates.First();
                tempCur.CurrencyName = currency.CurrencyName.Trim();
                tempCur.Rate = currency.Rate;
                tempCur.Note = currency.Note.Trim();
                tempCur.UpdateDate = DateTime.Now;

                DataSingleton.GetInstance().CurrencyExchangeRates.Context.SubmitChanges();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return false;
            }
            return true;
        }
    }
}